package cn.itcast.web.aspect;

import cn.itcast.domain.system.SysLog;
import cn.itcast.domain.system.User;
import cn.itcast.service.system.SysLogService;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.RequestMapping;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.lang.reflect.Method;
import java.util.Date;

/**
 * 切面类：编写增强业务方法
 * 配置：
 *  1切面类交给容器管理
 *  2声明切面类
 *  3在切面方法上配置通知类型和切入点
 */
@Component
@Aspect
public class LogAspect {

	@Autowired
	private SysLogService sysLogService;

	@Autowired
	private HttpServletRequest request;

	@Autowired
	private HttpSession session;

	/**
	 * 保存操作日志
	 *  环绕通知（参数：pjp）
	 *      pjp：获取当前执行的方法（方法对象 Method）
	 */
	@Around(value="execution(* cn.itcast.web.controller.*.*.*(..))")
	public Object aroud(ProceedingJoinPoint pjp) throws Throwable {
		SysLog log = new SysLog();
		log.setIp(request.getRemoteAddr()); //ip
		log.setTime(new Date());
		Object obj = session.getAttribute("loginUser");
		if(obj != null) {
			User user  = (User) obj;
			log.setUserName(user.getUserName());
			log.setCompanyId(user.getCompanyId());
			log.setCompanyName(user.getCompanyName());
		}
		//通过反射获取
		MethodSignature ms =(MethodSignature)pjp.getSignature(); //标记对象，内部封装了方法对象Method
		Method method = ms.getMethod();
		//操作的方法名
		log.setMethod(method.getName());
		//操作的中文描述
		if(method.isAnnotationPresent(RequestMapping.class)){
			//有指定注解
			RequestMapping annotation = method.getAnnotation(RequestMapping.class);
			String name = annotation.name();
			log.setAction(name);
		}

		sysLogService.save(log);
		return pjp.proceed();
	}
}
